package com.carman.pos.api;

import java.util.HashMap;
import java.util.Iterator;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;
import android.widget.Toast;

public class UsbApi{

	public static final int SUCCESS = 0;
	public static final int ERR = -1;

	private final static String TAG = "UsbApi";
	private final static String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
	private Context mContext;
	private UsbManager mUsbManager;
	private UsbDevice mDevice = null;
	private UsbDeviceConnection mConnection = null;
	private UsbEndpoint mEndpointIn = null;
	private UsbEndpoint mEndpointOut = null;
	private PendingIntent mPermissionIntent = null;
	
	
	public UsbApi(Context context) {
		mContext = context;
	}
	public boolean init() {
		mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
		mPermissionIntent = PendingIntent.getBroadcast(mContext, 0,new Intent(ACTION_USB_PERMISSION), 0);
		HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
		Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
		while (deviceIterator.hasNext()) {
			mDevice = deviceIterator.next();
			Log.i("USB", "VID=" + mDevice.getVendorId() + " PID="+ mDevice.getProductId());
			if (Usb.USB_CTRL_PRODUCT_ID == mDevice.getProductId() && Usb.USB_CTRL_VENDOR_ID == mDevice.getVendorId()) {
				mUsbManager.requestPermission(mDevice,mPermissionIntent);
				break;
			}
			mDevice = null;
		}
		if(mDevice == null) {
			return false;
		}
		
		if(!mUsbManager.hasPermission(mDevice)) {
			return false;
		}
		
		mConnection = mUsbManager.openDevice(mDevice);
		if (mConnection == null) {
			Log.e(TAG, "openDevice()----mConnection==null!!!");
			return false;
		}
		
		if (!InitIOConfig().booleanValue()) {
			mConnection.close();
			mConnection = null;
			return false;
		}
		return true;
	}
	
	public int write(byte[] writeBuffer, int offsetSize,int nBytesToWrite, int writeTimeOut) {
		// TODO Auto-generated method stub
		if (mConnection == null) {
			Log.e(TAG, "writeBuffer()---mConnection==null");
			return ERR;
		}
		int writeTrueSize = 16384;
		int writeStartSieze = 0;
		byte[] writeTrueBuffer = new byte[writeTrueSize];
		if (mEndpointOut == null) {
			Log.e(TAG, "writeBuffer()---mEndpointOut == null");
			return ERR;
		}
		int allTransferSize = 0;
		int bulkTransferSize = 0;
		if (nBytesToWrite > writeTrueSize) {
			for (int i = 0; i < nBytesToWrite / writeTrueSize; i++) {
				System.arraycopy(writeBuffer, writeStartSieze, writeTrueBuffer,
						0, writeTrueSize);

				bulkTransferSize = mConnection.bulkTransfer(
						mEndpointOut, writeTrueBuffer, offsetSize,
						writeTrueSize, writeTimeOut);
				allTransferSize += bulkTransferSize;
				writeStartSieze += writeTrueSize;
			}
			System.arraycopy(writeBuffer, writeStartSieze, writeTrueBuffer, 0,
					nBytesToWrite - writeStartSieze);
			bulkTransferSize = mConnection.bulkTransfer(mEndpointOut,
					writeTrueBuffer, offsetSize, nBytesToWrite
							- writeStartSieze, writeTimeOut);
			allTransferSize += bulkTransferSize;
			if (allTransferSize == nBytesToWrite)
				return SUCCESS;
		} else {
			bulkTransferSize = mConnection.bulkTransfer(mEndpointOut,
					writeBuffer, offsetSize, nBytesToWrite, writeTimeOut);
			if (bulkTransferSize == nBytesToWrite) {
				return SUCCESS;
			}
		}
		Log.e(TAG,"writeBuffer()--- ==> bulkTransferSize != nBytesToWrite!!!");
		return ERR;
	}
	
	public void destory() {
		if(mConnection != null) {
			mConnection.close();
		}
		mConnection = null;
	}
	
	private Boolean InitIOConfig() {
		mEndpointIn = null;
		mEndpointOut = null;
		if ((mDevice == null) || (mConnection == null)) {
			Log.e(TAG, "InitIOConfig()------mDevice == null) || (mConnection == null");
			return Boolean.valueOf(false);
		}
		int interfaceCount = 1;
		UsbInterface intf = null;
		UsbEndpoint endpoint = null;
		if (mDevice.getInterfaceCount() == 0) {
			Log.e(TAG, "InitIOConfig()------mDevice.getInterfaceCount() == 0");
			return Boolean.valueOf(false);
		}
		for (int n = 0; n < interfaceCount; n++) {
			intf = mDevice.getInterface(n);
			boolean forceClaim = true;
			mConnection.claimInterface(intf, forceClaim);

			int endpoitCount = intf.getEndpointCount();
			if (endpoitCount == 0) {
				return Boolean.valueOf(false);
			}
			for (int m = 0; m < endpoitCount; m++) {
				endpoint = intf.getEndpoint(m);
				if (endpoint.getType() == 2) {
					if (endpoint.getDirection() == 0)
						mEndpointOut = endpoint;
					else if (endpoint.getDirection() == 128) {
						mEndpointIn = endpoint;
					}
				}
			}
		}
		if ((mEndpointOut == null) || (mEndpointIn == null)) {
			Log.e(TAG,"InitIOConfig()------mEndpointOut == null) || (mEndpointIn == null");
			return Boolean.valueOf(false);
		}
		return Boolean.valueOf(true);
	}

}
